package com.linq.cool.common.core.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.linq.cool.common.constants.CacheConstants;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * @Author: yqlin
 * @Date: 2021/1/31 23:35
 * @Description: jwt
 * @Version: 1.0.0
 */
@Slf4j
public class JwtUtils {
    private final static String SECRET_KEY = "4a8f8226f04cfe5dabe8be4c6fb939c0.18061877017@163.com&linq.cool";

    public static void main(String[] args) {
        System.out.println(Md5Utils.toMD5("18061877017@163.com&linq.cool"));
    }

    /**
     * 校验token是否正确
     *
     * @param token 密钥
     *
     * @return 是否正确
     */
    public static boolean verify(String token, Long userId) {
        try {
            // 根据密码生成JWT效验器
            Algorithm algorithm = Algorithm.HMAC256(SECRET_KEY);
            JWTVerifier verifier = JWT.require(algorithm).withClaim("userId", userId).build();
            // 校验TOKEN
            verifier.verify(token);
            return true;
        } catch (Exception e) {
            log.error(e.getMessage());
            return false;
        }
    }

    /**
     * 获得token中的信息无需secret解密也能获得
     *
     * @return token中包含的用户名
     */
    public static Long getUserId(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("userId").asLong();
        } catch (JWTDecodeException e) {
            log.error(e.getMessage());
            return null;
        }
    }

    /**
     * 获得token中的信息无需secret解密也能获得
     *
     * @return token中包含的登录类型
     */
    public static Integer getLoginType(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("loginType").asInt();
        } catch (JWTDecodeException e) {
            log.error(e.getMessage());
            return null;
        }
    }


    /**
     * 生成签名,5min后过期
     *
     * @param userId    用户id
     * @param minites   过期时间
     * @param loginType 登录类型
     *
     * @return 加密的token
     */
    public static String sign(Long userId, Long minites, Integer loginType) {
        final long epireTime = minites * 60 * 1000;
        Date date = new Date(System.currentTimeMillis() + epireTime);
        Algorithm algorithm = Algorithm.HMAC256(SECRET_KEY);
        // 附带userId信息
        return JWT.create()
                .withClaim("userId", userId)
                .withClaim("loginType", loginType)
                .withExpiresAt(date).sign(algorithm);
    }


    /**
     * 根据request中的token获取用户账号
     *
     * @param request
     *
     * @return
     */
    public static Long getUserIdByToken(HttpServletRequest request) {
        Long userId = getUserId(getToken(request));
        if (userId == null) {
            log.info("解析不到userId");
        }
        return userId;
    }


    /**
     * 获取请求token
     */
    public static String getToken(HttpServletRequest request) {
        String token = request.getHeader(CacheConstants.HEADER);
        if (StringUtils.isNotEmpty(token) && token.startsWith(CacheConstants.TOKEN_PREFIX)) {
            token = token.replace(CacheConstants.TOKEN_PREFIX, "");
        }
        return token;
    }

}
